<template>
  <div>
    <el-button @click="back" style="margin-right: 2em">return</el-button>
    <el-button @click="random" style="margin-right: 2em">start</el-button>
    <el-button @click="end" style="margin-right: 2em">end</el-button>
    <el-button @click="next(line)" style="margin-right: 2em" v-for="line in types" :key="line">{{ line }}</el-button>
    <el-button @click="clean" style="margin-right: 2em">clean</el-button>
    <br>
    <el-button @click="toggle" style="margin-right: 2em">{{ set ? 'set' : 'get' }}</el-button>

    <!--  set  -->
    <template v-if="set">
      <el-input v-model="key"></el-input>
      <el-input v-model="type"></el-input>
      <codemirror
          v-model="value"
          :options="cmOption"
          @keyup.alt.enter.native="submit"
          class="codemirror-inner"
          ref="editor"
      />
      <el-button @click="submit">submit</el-button>
    </template>
    <!--  get  -->
    <template v-else>
      <el-input v-model="key" @keydown.native.enter="load" @keydown.native.tab="toggle" @input="clear"></el-input>
      <template v-if="type==='url'">
        <a :href="value" target="_blank" class="url">{{ key }}</a>
      </template>
      <template v-else-if="type==='urls'">
        <ul>
          <li v-for="line in split_rows(value)" :key="line[0]">
            <a :href="line[1]" target="_blank" class="url">{{ line[0] }}</a>
          </li>
        </ul>
      </template>
      <template v-else-if="type==='latex'">
        <ul>
          <li v-for="line in split_rows_one(value)" :key="line">
            <hr v-if="line==='---'">
            <div v-katex="line" v-else></div>
          </li>
        </ul>
      </template>
      <template v-else-if="type==='link'">
        <ul>
          <li v-for="line in split_rows_link(value)" :key="line[0]+line[3]">
            <div :style="{textIndent:line[1]*16*4+'px',display:'inline-block',color:'#333'}">·</div>

            <template v-if="line[2]==='link'">
              <MyLink :link="word" :style="{display:'inline-block'}" v-for="word in line[0].split(' ')" :key="word"
                      class="link">
                {{ word }}
              </MyLink>
            </template>
            <div @click="link(line[0])" :style="{display:'inline-block'}" v-else>{{ line[0] }}</div>
          </li>
        </ul>
      </template>
      <template v-else-if="type==='table'">
        <el-table :data="table(value)">
          <el-table-column :prop="i" v-for="i in range(value)" :key="i"></el-table-column>
        </el-table>
      </template>
      <template v-else-if="type==='img'">
        <el-image
            style="width: 50vw"
            :src="'http://114.115.136.139:8001/static/upload/'+value +'?' +Math.random()"
            :preview-src-list="['http://114.115.136.139:8001/static/upload/'+value + '?' + Math.random()]">
        </el-image>
      </template>
      <template v-else-if="type==='audio'">
        <audio :src="'http://114.115.136.139:8001/static/upload/'+value" controls loop>{{ key }}</audio>
      </template>
      <template v-else-if="type==='code'">
        <pre><code>{{ value }}</code></pre>
      </template>
      <template v-else-if="type==='table-2'">
        <el-table :data="table2(value)" :show-header="false">
          <el-table-column prop="key" min-width="30%"></el-table-column>
          <el-table-column prop="values">
            <template slot-scope="scope">
              <div v-for="words in scope.row['values'].split('|')" :key="words">
                {{ words }}
              </div>
            </template>
          </el-table-column>
        </el-table>
      </template>
      <template v-else-if="type==='mindmap'">
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" :width="width" :height="height" v-loading="loading">
          <MyNode ref="mindmap" :value="value" :data="data" :key_="key" :width="width" :height="height"></MyNode>
        </svg>
      </template>
      <template v-else>
        <div v-for="line in split_rows_text(value)" :key="line">
          <hr v-if="line.startsWith('hr')">
          <div v-else-if="line.trim().endsWith('$')">
            <div :style="{textIndent:(line.length-line.trim().length)*16*2+'px',color:'#333',display:'inline-block'}">
              ·
            </div>
            <span v-katex="line.trim().substr(1,line.trim().length-2)"></span>
          </div>
          <pre v-else>{{ line }}</pre>
        </div>
      </template>
    </template>
    <!--    <div id="descendants">-->
    <!--    </div>-->
    <div id="calculateWidth"></div>
  </div>
</template>

<script>
import {codemirror} from 'vue-codemirror'
// import mindmap from '@/components/mindmap'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/base16-dark.css'
import MyLink from '@/components/MyLink'
import MyNode from "@/components/MyNode";
import init from "@/utils";

export default {
  name: "home",
  components: {
    codemirror,
    // mindmap,
    MyLink,
    MyNode
  },
  data() {
    return {
      loading: true,
      width: '0px',
      height: '0px',
      defaultType: 'text',
      key: '',
      keys: [],
      value: '',
      set: false,
      type: 'text',
      cmOption: {
        indentWithTabs: true,
        indentUnit: 4,
        lineNumbers: true,
        mode: 'text/x-vue',
        theme: 'base16-light',
      },
      history: [],
      n: 0,
      types: [
        'next',
        // 'mindmap',
        // 'link',
        // 'url',
        // 'urls',
        // 'audio',
      ],
      clock: null,
      data: null
    }
  },
  methods: {
    clean() {
      let cleanValue = this.value
      this.getMindmapData('mindmap', cleanValue)
    },
    getMindmapData(type, beforeValue) {
      let value = beforeValue || this.value
      value = this.key + '\n\t' + value.replaceAll("\n", "\n\t")
      this.$axios.post('/api', {q: value}).then((r) => {
        let {data, width, height} = init(eval(r.data))
        this.width = width + 'px'
        this.height = height + 'px'
        this.data = data
        this.loading = false
        this.type = type === 'none' ? this.defaultType : type
      })
    },
    back() {
      this.history.pop()
      this.key = this.history[this.history.length - 1]
      this.load()
    },
    load() {
      if (this.history[this.history.length - 1] !== this.key) {
        this.history.push(this.key)
      }
      this.$axios.get('/get', {params: {key: this.key}}).then((r) => {
        this.value = r.data.value
        return r.data.type
      }).then((type) => {
        if (type === 'mindmap') {
          this.getMindmapData(type)
        } else {
          this.type = type === 'none' ? this.defaultType : type
        }
      })
    },
    submit() {
      this.$axios.post('/set', {key: this.key.trim(), value: this.value, type: this.type}).then(() => {
        this.toggle()
      })
    },
    link(value) {
      // this.$router.push('/home/' + value)
      this.key = value
      this.load()
    },
    toggle() {
      this.set = !this.set

      this.load()


      // if (!this.set && this.key !== '') {
      //   new Promise((resolve) => {
      //     this.load()
      //     resolve()
      //   }).then(() => {
      //     this.set = !this.set
      //   })
      // } else if (this.key === '') {
      //   // this.type = 'mindmap'
      //   this.set = !this.set
      // } else {
      //   this.set = !this.set
      // }
    },
    split_rows(rows) {
      const l = rows.split('\n')

      const ll = []
      for (let i = 0; i < l.length; i++) {
        const pair = l[i].split(' ')
        ll.push(pair)
      }
      return ll
    },
    split_rows_one(rows) {
      const l = rows.split('\n')
      return l
    },
    split_rows_link(rows) {
      const l = rows.split('\n')
      for (let i = 0; i < l.length; i++) {
        let line = l[i].trim()
        const tabs = (l[i].length - line.length) / 2
        let type;
        if (line.startsWith('- ')) {
          type = 'plain'
          line = line.slice(2)
        } else {
          type = 'link'
        }
        l[i] = [line, tabs, type, i]
      }

      return l
    },
    split_rows_text(rows) {
      let n = 0
      const l = []
      for (let row of this.split_rows_one(rows)) {
        if (row.trim().length !== 0) {
          l.push(row)
        } else {
          l.push('hr' + n++)
        }
      }
      return l
    },
    table2(rows) {
      const aList = rows.split('---')

      const ret = []

      for (let a of aList) {
        const bList = a.trim().split('\n')
        ret.push({key: bList[0], values: bList.slice(1).join('|')})
      }
      return ret
    },
    table(rows) {
      const ll = this.split_rows(rows)
      const ll_ = []

      for (let i = 0; i < ll.length; i++) {
        const l = ll[i];
        const l_ = {}
        for (let j = 0; j < l.length; j++) {
          l_['' + j] = l[j];
        }
        ll_.push(l_)
      }
      return ll_
    },
    range(rows) {
      const n = rows.split('\n')[0].split(' ').length
      const l = []
      for (let i = 0; i < n; i++) {
        l.push(i + '')
      }
      return l
    },
    clear() {
      this.value = ''
      this.type = this.defaultType
    },
    next(type) {
      let l
      if (type === 'next') {
        l = this.keys
      } else {
        l = this.keys.filter((x) => x.value.type === type)
      }
      this.key = l[Math.floor(Math.random() * (l.length - 1))].key
      this.n++
      this.load()
    },
    random() {
      this.clock = setInterval(() => {
        this.next('next')
      }, 3000)
    },
    end() {
      clearInterval(this.clock)
    },
    upload() {

    }
  }
  ,
  created() {
    document.addEventListener('keyup', (e) => {
      if (e.key == 'F2') {
        this.back()
      }
    })
    document.addEventListener('contextmenu', (e) => {
      if (e.button === 2) {
        this.back()
        e.preventDefault()
      }
    })
    this.key = this.$route.params['key']
    this.$axios.get('/keys').then((r) => {
      this.keys = r.data
    })
    this.load()
  },
  beforeRouteUpdate(to) {
    this.key = to.params['key']
    this.load()
  }
}
</script>

<style scoped>
.url {
  color: red;
}

hr {
  border-width: 0;
  margin: 30px 0;
}
</style>
